#ifndef CELLAR_H
#define CELLAR_H

#include "wine.h"
/**
 * @brief The Cellar class
 *
 * Container class for storing wine objects
 *
 * Includes functions for:
 * -calculating distances between two wine samples in 11-dim feature space
 * -predicting wine type and quality based on calculated distances
 * -splitting Cellar into training and validating sets
 *
 */




class Cellar{

public:


    enum distanceType{MANHATTAN = 1, SQUARED_EUCLIDEAN = 2, MINKOWSKI = 3};

    Cellar (std::vector<Wine>& w);

    Cellar(std::string& file, std::vector<double> p_low = std::vector<double>(), std::vector<double> p_dif = std::vector<double>());

    void find(Wine& w);

    std::vector<Wine> split_cellar(int a);

    Wine get_wine();

    bool is_empty() {return wines.empty();}

    std::pair<int,bool> predictClass();

    std::pair<Cellar,Cellar> splitToRedAndWhite();

    static std::pair<std::vector<Wine*>, std::vector<Wine*> > splitWineListToRedAndWhite(std::vector<Wine*>& allWines);

    //SETTERS
    void setMaxForFrequenceTesting(const int& value){param_maxForFrequenceTesting = value;}

    void setNumOfWinesForAveragePredict(const int& value){param_numOfWinesForAveragePredict = value;}

    void setThresholdForFrequenceTesting(const double& value){param_thresholdForFrequenceTesting = value;}

    void setWeightsForWines(const std::vector<double>& vector){param_weightsForFeatures = vector;}

    void setDistanceType(int currentType){mDistanceType = (distanceType)currentType;}

    void setQforMinkowski(double& value){ qForMinkowski = value;}


    std::vector<Wine>& getWines(){return wines;}
    std::vector<Wine*> getWinePointers();
    std::vector<double> getLow(){return lim_low;}
    std::vector<double> getDif(){return lim_dif;}
    std::vector<double> getWeights(){return param_weightsForFeatures;}
private:

    int averagePredict(int num, std::vector<Wine*>& wines_c);

    void initParams();

    double distanceManhattan(Wine& first, Wine& second);


    double distanceSquaredEuclidean(Wine& first, Wine& second);

    double distanceMinkowski(Wine& first, Wine& second);

    void copyValuesToAnotherCellar(Cellar& anotherCellar);


    std::vector<Wine> wines;
    std::vector<double> lim_low;
    std::vector<double> lim_dif;

    //parameters for testing
    enum distanceType mDistanceType;
    double qForMinkowski;
    int param_maxForFrequenceTesting;
    int param_numOfWinesForAveragePredict;
    double param_thresholdForFrequenceTesting;
    std::vector<double> param_weightsForFeatures;


};






#endif // CELLAR_H
